home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / tex / src / specialhost / specialparse.c < prev    next >
C/C++ Source or Header  |  1991-04-18  |  7KB  |  303 lines

  1. /* specialparse.c */
  2.  
  3. /************************************************************************/
  4. /* Some functions of this file are borrowed from Tomas Rokicki's    */
  5. /* printer driver "dvips". The functions GetKeyStr and GetKeyVal are,    */
  6. /* with little changes, from the file dospecial.c.            */
  7. /* "dvips" is a freely redistributable PostScript driver for dvi files.    */
  8. /* "dvips" is (C) Copyright 1987 by Tomas Rokicki.            */
  9. /*                                    */
  10. /*                    Georg Hessmann   26.06.1990    */
  11. /************************************************************************/
  12.  
  13.  
  14. KeyDesc KeyTab[] = 
  15.  {{"ifffile", String},            /* ok */
  16.   {"hsize",   Dimension},        /* ok */
  17.   {"vsize",   Dimension},        /* ok */
  18.   {"hoffset", Dimension},        /* ok */
  19.   {"voffset", Dimension},        /* ok */
  20.   {"scale",   Number},            /* not implemented */
  21.   {"hscale",  Number},            /* not implemented */
  22.   {"vscale",  Number},            /* not implemented */
  23.   {"mode",    String},            /* new by MiL */
  24.   {"red",     Number},            /* new by MiL */
  25.   {"green",   Number},            /* new by MiL */
  26.   {"blue",    Number},            /* new by MiL */
  27.   {"gamma",   Number}};            /* new by MiL */
  28.   
  29. #define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0]))
  30.  
  31.  
  32.  
  33.  
  34. /* local funktions */
  35. static    void    offset_to_inch        (float *, float *, unsigned short);
  36. static    char   *GetKeyStr        (char *str, KeyWord *kw);
  37. static  int    GetKeyVal        (KeyWord *kw, KeyDesc tab[],
  38.                      int nt, int *tno);
  39.  
  40.  
  41.  
  42.  
  43. /*******   P A R S E R   *******************/
  44.  
  45.  
  46. /* Umrechnung von 'offset' nach inch */ 
  47. static void offset_to_inch(float *inch,float *offset,unsigned short einh)
  48. {
  49.   float temp;
  50.  
  51.   /** einh == pt|pc|in|bp|cm|mm|dd|cc **/
  52.   switch (einh) {
  53.     case 0x7074:        /* pt */
  54.     temp = (float)*offset / 72.27;
  55.     break;
  56.     case 0x7063:        /* pc */
  57.     temp = (float)*offset / 6.0225;
  58.     break;
  59.     case 0x696e:        /* in */
  60.     temp = (float)*offset;
  61.     break;
  62.     case 0x6270:        /* bp */
  63.     temp = (float)*offset / 72.0;
  64.     break;
  65.     case 0x636d:        /* cm */
  66.     temp = (float)*offset / 2.5322;
  67.     break;
  68.     case 0x6d6d:        /* mm */
  69.     temp = (float)*offset / 25.322;
  70.     break;
  71.     case 0x6464:        /* dd */
  72.     temp = (float)*offset / 67.3467;
  73.     break;
  74.     case 0x6363:        /* cc */
  75.     temp = (float)*offset / 5.6146;
  76.     break;
  77.     default:
  78.      temp = *offset;        /* NOP */
  79.     break;
  80.   }
  81.  
  82.   *inch = temp;
  83. }
  84.  
  85.  
  86. /**********************************************************************/
  87. /*****************************  GetKeyStr  ****************************/
  88. /**********************************************************************/
  89.  
  90. /* extract first keyword-value pair from string (value part may be null)
  91.  * return pointer to remainder of string
  92.  * return NULL if none found
  93.  */
  94.  
  95. static char *GetKeyStr( char *str, KeyWord *kw )
  96. {
  97.   char *s, *k, *v, t;
  98.  
  99.   if ( str== NULL ) {
  100.     return( NULL );
  101.   }
  102.  
  103.   for ( s=str; *s == ' '; s++ );     /* skip over blanks */
  104.   if ( *s == '\0' ) {
  105.     return( NULL );
  106.   }
  107.  
  108.   for ( k=kw->Key;            /* extract keyword portion */
  109.        (*s != ' ') && (*s != '\0') && (*s != '='); 
  110.        *k++ = *s++ );
  111.  
  112.   *k = '\0';
  113.   v = NULL;
  114.   kw->Val[0] = '\0';
  115.   kw->vt = None;
  116.  
  117.   for ( ; *s == ' '; s++ );        /* skip over blanks */
  118.  
  119.   if ( *s != '=' ) {            /* look for "=" */
  120.     return( s );
  121.   }
  122.  
  123.   for( s++ ; *s == ' '; s++ );        /* skip over blanks */
  124.   if ( *s == '\'' || *s == '\"' ) {    /* get string delimiter */
  125.     t = *s++;
  126.   }
  127.   else {
  128.     t = ' ';
  129.   }
  130.   for (v=kw->Val;            /* copy value portion up to delim */
  131.       *s != t && *s != '\0';
  132.       *v++ = *s++ ) ;
  133.  
  134.   if ( t != ' ' && *s == t ) {
  135.     s++;
  136.   }
  137.  
  138.   *v = '\0';
  139.   kw->vt = String;
  140.  
  141.   return( s );
  142. }
  143.  
  144. /**********************************************************************/
  145. /*****************************  GetKeyVal  ****************************/
  146. /**********************************************************************/
  147.  
  148. /* get next keyword-value pair
  149.  * decode value according to table entry
  150.  */
  151.  
  152. static int GetKeyVal( KeyWord *kw, KeyDesc tab[], int nt, int *tno)
  153. {
  154.   int i;
  155.   unsigned short ei;
  156.   char *einh;
  157.   float f;
  158.  
  159.   einh = (char *)&ei;
  160.   ei = 0;
  161.   *tno = -1;
  162.  
  163.   for(i=0; i<nt; i++) {
  164.     if ( !strcmp(kw->Key, tab[i].Entry) ) {
  165.       *tno = i;
  166.       switch ( tab[i].Type ) {
  167.         case None: 
  168.             if ( kw->vt != None ) {
  169.               return( FALSE );
  170.             }
  171.             break;
  172.         case String:
  173.             if ( kw->vt != String ) {
  174.               return( FALSE );
  175.             }
  176.             break;
  177.         case Integer:
  178.             if ( kw->vt != String ) {
  179.               return( FALSE );
  180.             }
  181.             if ( sscanf(kw->Val,"%d", &(kw->v.i)) != 1) {
  182.               return( FALSE );
  183.             }
  184.             break;
  185.         case Dimension:
  186.             if (kw->vt != String ) {
  187.               return( FALSE );
  188.             }
  189.             if (sscanf(kw->Val,"%f%2s", &f, einh) != 2) {
  190.               return( FALSE );
  191.             }
  192.             offset_to_inch((float *)&(kw->v.n),&f,ei);
  193.             break;
  194.         case Number:
  195.             if ( kw->vt != String ) {
  196.               return( FALSE );
  197.             }
  198.             if( sscanf(kw->Val,"%f", &(kw->v.n)) != 1) {
  199.               return( FALSE );
  200.             }
  201.             break;
  202.      }
  203.      kw->vt = tab[i].Type;
  204.      return( TRUE );
  205.     }
  206.   }
  207.   return( TRUE );
  208. }
  209.  
  210.  
  211. /*--------------------------------------------------------------------*/
  212.  
  213. /**********************************************************************/
  214. /****************************  ParseSepcial  **************************/
  215. /**********************************************************************/
  216.  
  217. void ParseSpecial (char *str, struct parse_result *res)
  218.   /* interpret a \special command, made up of keyword=value pairs */
  219. {
  220.   KeyWord k;
  221.   int i;
  222.   
  223.   while( (str=GetKeyStr(str,&k)) != NULL ) {    /* get all keyword-value pairs */
  224.  
  225.     /* for compatibility, single words are taken as file names */
  226.     if ( k.vt == None /* && access(k.Key,0) == 0 */) {
  227.       strcpy(res->iffile, k.Key);
  228.     }
  229.     else if (GetKeyVal(&k, KeyTab, NKEYS, &i) && i != -1) {
  230.        switch (i) {
  231.          case IFFILE:
  232.             strcpy(res->iffile, k.Val);
  233.             break;
  234.          case HSIZE:
  235.             res->hsize = k.v.n;
  236.             break;
  237.          case VSIZE:
  238.             res->vsize = k.v.n;
  239.             break;
  240.          case HOFFSET:
  241.             res->hoffset = k.v.n;
  242.             break;
  243.          case VOFFSET:
  244.             res->voffset = k.v.n;
  245.             break;
  246.          case SCALE:
  247.             res->scale = k.v.n;
  248.             break;
  249.          case HSCALE:
  250.             res->hscale = k.v.n;
  251.             break;
  252.          case VSCALE:
  253.             res->vscale = k.v.n;
  254.             break;
  255.          case MODE:
  256.         if (!strcmp(k.Val, "bw")) res->mode = BandW;
  257.         else if (!strcmp(k.Val, "gray"))
  258.         {
  259.          res->mode = Gray;
  260.          res->red = 1.0;
  261.          res->green = 1.0;
  262.          res->blue = 1.0;
  263.         }
  264.         else if (!strcmp(k.Val, "color"))
  265.         {
  266.          res->mode = Color;
  267.          res->red = 2.99;
  268.          res->green = 5.87;
  269.          res->blue = 1.14;
  270.         }
  271.         else if (!strcmp(k.Val, "ham"))
  272.         {
  273.          res->mode = Ham;
  274.          res->red = 2.99;
  275.          res->green = 5.87;
  276.          res->blue = 1.14;
  277.         }
  278.         else res->mode = BandW;
  279.         break;
  280.          case RED:
  281.             res->red = k.v.n;
  282.         break;
  283.              case GREEN:
  284.              res->green = k.v.n;
  285.         break;
  286.          case BLUE:
  287.             res->blue = k.v.n;
  288.         break;
  289.          case GAMMA:
  290.             res->gamma = k.v.n;
  291.         break;
  292.          default:
  293.             pline("%f @%s\n", k.v.n, KeyTab[i].Entry);
  294.             break;
  295.            }
  296.     }
  297.     else {
  298.       pline("Invalid keyword or value in \\special: (%d)",i);
  299.       pline("    \"%s\" ignored", k.Key );
  300.     }
  301.   }
  302. }
  303.